﻿namespace Single.Lock
{
    public static class MutexHelper
    {
        public static T UseWaitLock<T>(string position, string key, string value, int minutes, Func<T> func)
        {
            using (Mutex mutex = new Mutex(false, $"{position}:{key}:{value}"))
            {
                mutex.WaitOne(TimeSpan.FromMinutes(minutes));

                try
                {
                    return func.Invoke();
                }
                finally
                {
                    mutex.ReleaseMutex(); mutex.Close();
                }
            }
        }

        public static void UseWaitLock(string position, string key, string value, int minutes, Action action)
        {
            UseWaitLock(position, key, value, minutes, () => { action.Invoke(); return true; });
        }

        public static T UseFirstLock<T>(string position, string key, string value, Func<T> func, Func<T> elseFunc)
        {
            using (Mutex mutex = new Mutex(true, $"{position}:{key}:{value}", out bool createNew))
            {
                try
                {
                    return createNew ? func.Invoke() : elseFunc.Invoke();
                }
                finally
                {
                    if (createNew) mutex.ReleaseMutex(); mutex.Close();
                }
            }
        }

        public static void UseFirstLock(string position, string key, string value, Action action, Action elseAction)
        {
            UseFirstLock(position, key, value, () => { action.Invoke(); return true; }, () => { elseAction.Invoke(); return true; });
        }
    }
}